package lsysteem;

import java.util.Stack;
import java.util.Vector;

public class LSTurtle extends Thread
{
	private static final int MAX_ITERATIONS = 7;
	private static final int LINE_LENGTH = 5;

	private int _iteration;
	private LSystem _modelData;
	private LSView _view;
	
	private LSLine _currentPosition = new LSLine();
	private LSStack _positionStack = new LSStack();
	public Vector<LSLine> closedList = new Vector();

	public LSTurtle(IModelData md, LSView v, int i)
	{
		super("LSTurtle");

		if (md instanceof LSystem)
			_modelData = (LSystem) md;
		
		_currentPosition.direction = -25;
		_currentPosition.x = 100;
		_currentPosition.y = 400;
		
		_view = v;
		_iteration = 0;
	}

	public void run()
	{
		System.out.println("Turtleing");
		
		LSNode string = new LSNode();
		string.value = _modelData.axioma;
		
		while (_iteration < MAX_ITERATIONS) {
			// Replace all characters with the in the rules given values
			LSNode currentChar = string;
			LSNode tempString = null;
			
			// Loop trough all characters in the current string
			while(currentChar != null)
			{
				// Found something to replace
				if(_modelData.rules.containsKey(currentChar.value))
				{
					// Create a copy of the nodes, and append those to the current string
					if(tempString != null)
						tempString.appendLast(_modelData.rules.get(currentChar.value).clone());
					else
						tempString = _modelData.rules.get(currentChar.value).clone();
				}
				// No? Leave the character...
				else
				{
					if(tempString != null){
						//tempString.appendLast(currentChar.clone());
						LSNode tmpNode = new LSNode();
						tmpNode.value = currentChar.value;
						tempString.appendLast(tmpNode);
					}
						
					else
						tempString = currentChar.clone();
				}
				
				
				currentChar = currentChar.next;
				
			}
			
			string = tempString;
			//System.out.println(string);
			_iteration++;
			try {
				Thread.sleep(200l);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
			Thread.yield();
		}
		
		draw(string);
		closedList.add(_currentPosition);
		
		_view.repaint();

	}

	private boolean isInClosedList(LSLine line)
	{
		for(LSLine item:closedList)
		{
			if(line.equals(item))
			{
				return true;
			}
		}
		return false;
	}
	
	private void draw(LSNode currentChar)
	{
		while(currentChar != null)
		{
			if(currentChar.value == '+')
			{
				_currentPosition.direction -= _modelData.angle;
			}
			else if(currentChar.value == '-')
			{
				_currentPosition.direction += _modelData.angle;
			}
			else if(currentChar.value == '[')
			{
				_positionStack.push(_currentPosition);
			}
			else if(currentChar.value == ']')
			{
				_currentPosition = _positionStack.pop();
			}
			else if(currentChar.value == 'F')
			{
				// Add this line to the closed list
				closedList.add(_currentPosition);
				
				LSLine tempPosition = new LSLine();
				tempPosition.previous = _currentPosition;
				tempPosition.x = _currentPosition.x + (int) (Math.cos(Math.toRadians(_currentPosition.direction))*LINE_LENGTH);
				tempPosition.y = _currentPosition.y + (int) (Math.sin(Math.toRadians(_currentPosition.direction))*LINE_LENGTH);
				tempPosition.direction = _currentPosition.direction;
				_currentPosition = tempPosition;
				
			}
			currentChar = currentChar.next;
		}
	
	}
}
